package sql;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import dao.SourceMapper;
import dao.TargetMapper;
import entity.ColumnDefine;
import entity.IndexDefine;
import entity.PKColumnDefine;
import entity.SequenceDefine;
import entity.TableDefine;

public class SqlExecutor {
	private SqlSessionFactory sourceFactory;
	private SqlSessionFactory targetFactory;
	private static SqlExecutor instance = new SqlExecutor();
	
	private SqlExecutor(){
		InputStream sourceInputStream;
		InputStream targetInputStream;
		InputStream propertiesStream;
		Properties properties;
	    
		try {
			sourceInputStream = Resources.getResourceAsStream("mybatis-config-source.xml");
			targetInputStream = Resources.getResourceAsStream("mybatis-config-target.xml");
			propertiesStream =  Resources.getResourceAsStream("config.properties");//new FileInputStream(new File("config.properties")); 
			properties = new Properties();
			properties.load(propertiesStream);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		// 创建会话工厂，传入mybatis的配置文件信息
		this.sourceFactory = new SqlSessionFactoryBuilder().build(sourceInputStream,properties);
		this.targetFactory = new SqlSessionFactoryBuilder().build(targetInputStream,properties);
	}
	
	public static SqlExecutor getInstance(){
		return instance;
	}
	
	public List<TableDefine> queryTables(String sql){
		SqlSession session = null;
		try{
			// 通过工厂得到SqlSession
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.queryTables(sql);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public List<PKColumnDefine> queryPkColumns(String sql){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.queryPkColumns(sql);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public List<ColumnDefine> queryColumns(String sql){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.queryColumns(sql);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public int countTable(String tableName){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.countData(tableName);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public String QueryTableComments(String tableName){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.QueryTableComments(tableName);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public List<HashMap<String,Object>> loadData(String tableName,String pkColumns,int start,int end){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.loadData(tableName, pkColumns, start, end);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public List<IndexDefine> queryIndex(String sql){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.queryIndex(sql);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public List<SequenceDefine> querySequence(String sql){
		SqlSession session = null;
		try{
			session = sourceFactory.openSession();
			SourceMapper mapper = session.getMapper(SourceMapper.class);
			return mapper.querySequence(sql);
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public void ddlOperator(String sql){
		SqlSession session = null;
		try{
			session = targetFactory.openSession();
			TargetMapper mapper = session.getMapper(TargetMapper.class);
		    mapper.ddlOperator(sql);
		    session.commit();
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	
	public void insert(List<HashMap<String,Object>> lst,String tableName){
		SqlSession session = null;
		try{
			session = targetFactory.openSession(ExecutorType.BATCH,false);
			TargetMapper mapper = session.getMapper(TargetMapper.class);
			for(HashMap<String,Object> map : lst){
				try{
				map.remove("DEF_ROWNO");
				mapper.insert(tableName, map);
				}catch(Throwable e){
					throw new RuntimeException(e);
				}
			}
			session.commit();
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public void tryDropTable(String tableName){
		SqlSession session = null;
		try{
			session = targetFactory.openSession();
			TargetMapper mapper = session.getMapper(TargetMapper.class);
			mapper.tryDropTable(tableName);
			session.commit();
		}catch(Throwable e){
			e.getMessage();
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
	
	public void tryDropIndex(String indexName){
		SqlSession session = null;
		try{
			session = targetFactory.openSession();
			TargetMapper mapper = session.getMapper(TargetMapper.class);
			mapper.tryDropIndex(indexName);
			session.commit();
		}catch(Throwable e){
			
		}finally{
			if(session != null){
				session.close();
			}
		}
	}
}
